package com.lnj.community.config;

import com.lnj.community.quartz.AlphaJob;
import com.lnj.community.quartz.CustomJobFactory;
import com.lnj.community.quartz.PostScoreRefreshJob;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

import javax.sql.DataSource;
import java.util.concurrent.Executor;

// 配置 -> 数据库 -> 调用
@Configuration
public class QuartzConfig {
    @Autowired
    private DataSource dataSource;
    @Autowired
    private Executor taskExecutor;
    @Autowired
    private CustomJobFactory customJobFactory;

    //BeanFactory: 只管理Bean的实例化, 配置, 生命周期, 管理等, 但是不管理Bean之间的依赖关系.
    //FactoryBean: 可以简化Bean的实例化过程, 可以管理Bean之间的依赖关系.

    // FactoryBean可简化Bean的实例化过程:
    // 1.通过FactoryBean封装Bean的实例化过程.
    // 2.将FactoryBean装配到Spring容器里. Spring会自动调用FactoryBean的getObject方法来获取Bean.
    // 3.将FactoryBean注入给其他的Bean.
    // 4.该Bean得到的是FactoryBean所管理的对象实例.

    // 配置JobDetail
    //JobDetailFactoryBean是Quartz提供的一个JobDetail工厂类, 用于创建一个JobDetail.
    //这里new JobDetailFactoryBean()是创建了一个JobDetail工厂类的实例.
    //通过getObject()方法可以获取到JobDetail工厂类的实例.
    // @Bean
    public JobDetailFactoryBean alphaJobDetail() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(AlphaJob.class);
        factoryBean.setName("alphaJob");
        factoryBean.setGroup("alphaJobGroup");
        factoryBean.setDurability(true);
        factoryBean.setRequestsRecovery(true);
        return factoryBean;
    }

    // 配置Trigger(SimpleTriggerFactoryBean, CronTriggerFactoryBean)
    //SimpleTriggerFactoryBean是Quartz提供的一个简单的Trigger工厂类, 用于创建一个简单的Trigger.
    //CronTriggerFactoryBean是Quartz提供的一个Cron表达式Trigger工厂类, 用于创建一个Cron表达式Trigger.
    // @Bean
    public SimpleTriggerFactoryBean alphaTrigger(JobDetail alphaJobDetail) {
        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        factoryBean.setJobDetail(alphaJobDetail);
        factoryBean.setName("alphaTrigger");
        factoryBean.setGroup("alphaTriggerGroup");
        //设置为3秒执行一次
        factoryBean.setRepeatInterval(3000);
        factoryBean.setJobDataMap(new JobDataMap());
        return factoryBean;
    }


    // 刷新帖子分数任务
    @Bean
    public JobDetailFactoryBean postScoreRefreshJobDetail() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        //创建JobDetail工厂类的实例 设置Job任务
        factoryBean.setJobClass(PostScoreRefreshJob.class);
        //设置JobDetail的名称
        factoryBean.setName("postScoreRefreshJob");
        //设置JobDetail的组名
        factoryBean.setGroup("communityJobGroup");
        //设置JobDetail的持久化
        factoryBean.setDurability(true);
        //设置JobDetail的恢复
        factoryBean.setRequestsRecovery(true);

        return factoryBean;
    }

    @Bean
    public SimpleTriggerFactoryBean postScoreRefreshTrigger(JobDetail postScoreRefreshJobDetail) {
        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        //创建SimpleTrigger工厂类的实例 设置Trigger任务
        factoryBean.setJobDetail(postScoreRefreshJobDetail);
        //设置Trigger的名称
        factoryBean.setName("postScoreRefreshTrigger");
        //设置Trigger的组名
        factoryBean.setGroup("communityTriggerGroup");
        //设置Trigger的重复间隔 5分钟执行一次
        factoryBean.setRepeatInterval(1000 * 60 * 5);
        //设置JobDataMap 用于传递参数
        factoryBean.setJobDataMap(new JobDataMap());
        return factoryBean;
    }

    // 配置SchedulerFactoryBean
    //SchedulerFactoryBean是Quartz提供的一个Scheduler工厂类, 用于创建一个Scheduler.
    //Scheduler是Quartz的核心, 它负责调度JobDetail和Trigger.

    //alphaJobDetail和alphaTrigger是Quartz提供的JobDetail和Trigger工厂类的实例.
    //postScoreRefreshJobDetail和postScoreRefreshTrigger是自定义的JobDetail和Trigger工厂类的实例.
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(JobDetail postScoreRefreshJobDetail, SimpleTriggerFactoryBean postScoreRefreshTrigger) {
        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
        // 显式设置数据源
        factoryBean.setDataSource(dataSource);
        // 设置JobDetail
        factoryBean.setJobDetails(postScoreRefreshJobDetail);
        // 设置Trigger
        factoryBean.setTriggers(postScoreRefreshTrigger.getObject());
        // 设置自定义的 JobFactory
        factoryBean.setJobFactory(customJobFactory);
        // 设置调度器名称
        factoryBean.setSchedulerName("communityScheduler");
        // 自动启动调度器
        factoryBean.setAutoStartup(true);
        // 覆盖已存在的任务
        factoryBean.setOverwriteExistingJobs(true);
        // 设置线程池
        factoryBean.setTaskExecutor(taskExecutor);

        return factoryBean;
    }
    @Bean
    public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) {
        return schedulerFactoryBean.getScheduler();
    }

}
